package commRedisStatus

import (
	"encoding/json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedis"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Number"
	"strconv"
	"sync"
)

type redisStatusConsumerService struct {
	mutex  sync.RWMutex // 读写锁
	values map[string]interface{}
}

func (e *redisStatusConsumerService) GetValues() map[string]interface{} {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	return Map.Clone(e.values)
}

func (e *redisStatusConsumerService) GetValue(key string) interface{} {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	return e.values[key]
}

func (e *redisStatusConsumerService) setValue(key string, value interface{}) {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	e.values[key] = value
}

func (e *redisStatusConsumerService) clearValue() {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	e.values = make(map[string]interface{})
}

func (e *redisStatusConsumerService) Load() error {
	// 先读取redis的时间戳表
	jsnTime, err := commRedis.Client.HGetAll(keySync).Result()
	if err != nil {
		return err
	}

	// 循环读取具体的数据
	for key, val := range jsnTime {
		// 转换格式
		updateTime, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			continue
		}

		// 取出一个元素，如果没有就添加一个默认值
		cacheData := make(map[string]interface{})
		ptr := e.GetValue(key)
		if ptr == nil {
			cacheData = make(map[string]interface{})
			cacheData[keyActiveTime] = int64(-1)
		} else {
			cacheData = ptr.(map[string]interface{})
		}

		// 将interface{}转换成整数
		activeTime := Number.MakeInt64(Map.GetOrDefault(cacheData, keyActiveTime, float64(-1)))

		// 检查：数据是否发生了变化
		if activeTime == updateTime {
			continue
		}

		jsn, err := commRedis.Client.HGet(keyData, key).Result()
		if err != nil {
			continue
		}

		if jsn == "" {
			continue
		}

		redisData := make(map[string]interface{})
		err = json.Unmarshal([]byte(jsn), &redisData)
		if err != nil {
			return err
		}

		// 数据部分，至少包含一个时间字段
		_, ok := redisData[keyActiveTime]
		if !ok {
			redisData[keyActiveTime] = int64(-1)
		}

		e.setValue(key, redisData)
	}

	return nil
}
